#include <fstream>
#include <iostream>

#include <boost/lexical_cast.hpp>
#include <boost/tokenizer.hpp>
#include <boost/algorithm/string.hpp>

#include <Wt/WAnchor>
#include <Wt/WApplication>
#include <Wt/WEnvironment>
#include <Wt/WLogger>
#include <Wt/WMenu>
#include <Wt/WPushButton>
#include <Wt/WStackedWidget>
#include <Wt/WTabWidget>
#include <Wt/WTable>
#include <Wt/WTableCell>
#include <Wt/WTemplate>
#include <Wt/WText>
#include <Wt/WViewWidget>
#include <Wt/WVBoxLayout>
#include <Wt/WStandardItemModel>
#include <Wt/WTable>
#include <Wt/WComboBox>

#include "Home.h"
#include "download.h"

static const std::string SRC_INTERNAL_PATH = "src";

Home::~Home()
{
}

Home::Home(const WEnvironment& env, const std::string& title,
		   const std::string& resourceBundle, const std::string& cssPath)
	: WApplication(env),
	  homePage_(0),
	  m_download(0)
{
	messageResourceBundle().use(appRoot() + resourceBundle, false);

	useStyleSheet(cssPath + "/wt.css");
	useStyleSheet(cssPath + "/wt_ie.css", "lt IE 7");
	useStyleSheet("css/home.css");
	useStyleSheet("css/sourceview.css");
	setTitle(title);

	setLocale("");
	language_ = 0;
	init();
}

void Home::init()
{
	internalPathChanged().connect(this, &Home::setup);
	internalPathChanged().connect(this, &Home::logInternalPath);

	setup();
}

void Home::setup()
{
	if (!homePage_) {
		root()->clear();
		homePage_ = initHome();
		root()->addWidget(homePage_);
	}
}

WWidget *Home::initHome()
{
	WTemplate *result = new WTemplate(tr("template"), root());

	WContainerWidget *languagesDiv = new WContainerWidget();

	WStackedWidget *contents = new WStackedWidget();
	WAnimation fade(WAnimation::Fade, WAnimation::Linear, 250);
	contents->setTransitionAnimation(fade);
	contents->setId("main_page");

	mainMenu_ = new WMenu(contents, Vertical);
	mainMenu_->setRenderAsList(true);

	mainMenu_->addItem
	(tr("introduction"), introduction())->setPathComponent("");

	mainMenu_->addItem
	(tr("features"), wrapView(&Home::features), WMenuItem::PreLoading);

	mainMenu_->addItem
	(tr("documentation"), wrapView(&Home::documentation),
	 WMenuItem::PreLoading);

	mainMenu_->addItem
	(tr("faq"), wrapView(&Home::faq),
	 WMenuItem::PreLoading);

//	mainMenu_->addItem
//	(tr("download"), deferCreate(boost::bind(&Home::download, this)),
//	 WMenuItem::PreLoading);

	mainMenu_->itemSelectRendered().connect(this, &Home::updateTitle);

	mainMenu_->itemSelected().connect(this, &Home::googleAnalyticsLogger);

	// Make the menu be internal-path aware.
	mainMenu_->setInternalPathEnabled("/");

	sideBarContent_ = new WContainerWidget();

	result->bindWidget("languages", languagesDiv);
	result->bindWidget("menu", mainMenu_);
	result->bindWidget("contents", contents);
	result->bindWidget("sidebar", sideBarContent_);

	return result;
}

void Home::updateTitle()
{
	if (mainMenu_->currentItem()) {
		setTitle(tr("wt") + " - " + mainMenu_->currentItem()->text());
	}
}

void Home::logInternalPath(const std::string& path)
{
	// simulate an access log for the interal paths
	log("path") << path;
	googleAnalyticsLogger();
}

WWidget *Home::introduction()
{
	WContainerWidget* widget = new WContainerWidget();
	widget->addWidget(deferCreate(boost::bind(&Home::download, this)));
	return widget;
}

WWidget *Home::features()
{
	return new WText(tr("home.features"));
}

WWidget *Home::documentation()
{
	WText *result = new WText(tr("home.documentation"));
	result->setInternalPathEncoding(true);
	return result;
}

WWidget *Home::faq()
{
	return new WText(tr("home.faq"));
}

WWidget *Home::wrapView(WWidget *(Home::*createWidget)())
{
	return makeStaticModel(boost::bind(createWidget, this));
}

WWidget *Home::download()
{
	if (!m_download)
		m_download = new Download();
	return m_download;
}

WString Home::tr(const char *key)
{
	return WString::tr(key);
}

void Home::googleAnalyticsLogger()
{
	std::string googleCmd =
		"if (window.pageTracker) {"
		"""try {"
		""  "setTimeout(function() {"
		""  "window.pageTracker._trackPageview(\""
		+ environment().deploymentPath() + internalPath() + "\");"
		""  "}, 1000);"
		"""} catch (e) { }"
		"}";

	doJavaScript(googleCmd);
}

WApplication *createHomeApplication(const WEnvironment& env)
{
	return new Home(env, "Mu, Improve your memory", "wt-home", "css/wt");
}
